package com.easygo.controller;

import com.easygo.common.PageUtils;
import com.easygo.pojo.Goods;
import com.easygo.service.GoodsService;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.context.annotation.Scope;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@RestController
@Scope("prototype")
public class GoodsController {

    @Resource
    GoodsService goodsService;

    @Resource
    ElasticsearchTemplate elasticsearchTemplate;

    @RequestMapping("/search/{pageIndex}/{pageSize}")
    public PageUtils<Goods> search(@RequestParam("keywords") String keywords, @PathVariable("pageIndex") Integer pageIndex, @PathVariable("pageSize") Integer pageSize){
        Pageable pageable = PageRequest.of(pageIndex-1,pageSize);
        Page<Goods> page = goodsService.findGoodsByGoodsNameOrCaption(keywords, keywords, pageable);
        PageUtils<Goods> pageUtils =  new PageUtils<Goods>(pageIndex,pageSize,page.getTotalElements(),page.getContent());
        //查看records中的小图片
        for (Goods g:pageUtils.getRecords()) {
            System.out.println(g);
            System.out.println("url:"+g.getSmallPic());
        }
        return pageUtils;
    }


    /**
     *  term查询高亮(多字段查询)
     */
    @RequestMapping("/queryPage/{pageIndex}/{pageSize}")
    public PageUtils<Goods> queryPage(@RequestParam("keywords") String keywords, @PathVariable("pageIndex") Integer pageIndex,  @PathVariable("pageSize") Integer pageSize) {

        //设置高亮的规则
        HighlightBuilder.Field nameField = new HighlightBuilder
                .Field("*")
                .preTags("<span style='color:red'>")
                .postTags("</span>").requireFieldMatch(false);

        //多字段查询，可同时在name和description查询 对应实体类中的属性名
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.multiMatchQuery(keywords, "goodsName", "caption"))
                .withPageable(PageRequest.of(pageIndex - 1, pageSize))
                .withHighlightFields(nameField)
                .build();
        AggregatedPage<Goods> page = elasticsearchTemplate.
                queryForPage(nativeSearchQuery, Goods.class, new SearchResultMapper() {
                    @Override
                    public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
                        SearchHits searchHits = response.getHits();
                        SearchHit[] hits = searchHits.getHits();
                        ArrayList<Goods> products = new ArrayList<Goods>();
                        for (SearchHit hit : hits) {
                            Goods g = new Goods();
                            //原始map
                            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                            g.setId(Long.parseLong(sourceAsMap.get("id").toString())); //ID普通字段
                            g.setGoodsName(sourceAsMap.get("goodsName").toString()); // 普通显示
                            g.setCaption(sourceAsMap.get("caption").toString()); // 普通副标题
                            g.setPrice(Double.parseDouble(sourceAsMap.get("price").toString()));//商品价格
                            g.setSmallPic(sourceAsMap.get("smallPic").toString()); //商品图片
                            //高亮
                            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                            System.out.println(highlightFields);
                            if (highlightFields.get("goodsName") != null) {
                                String nameHighlight = highlightFields.get("goodsName").getFragments()[0].toString();
                                g.setGoodsName(nameHighlight);
                            }
                            if (highlightFields.get("caption") != null) {
                                String contentHighlight = highlightFields.get("caption").getFragments()[0].toString();
                                g.setCaption(contentHighlight);
                            }
                            products.add(g);
                        }
                        return new AggregatedPageImpl<T>((List<T>) products);
                    }
                });
        return new PageUtils<Goods>(pageIndex,pageSize,page.getTotalElements(),page.getContent());
    }

}
